package sau.diyizu.media.music;

import android.Manifest;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.Lifecycle;
import androidx.recyclerview.widget.RecyclerView;

import sau.diyizu.media.ItemListener;
import sau.diyizu.media.R;
import sau.diyizu.media.bean.Music;
import sau.diyizu.media.common.BaseFragment;
import sau.diyizu.media.common.RenameDialog;
import sau.diyizu.media.menu.MenuDialog;
import sau.diyizu.media.menu.MenuItem;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;

/**
 @author JYD
 @version 1.0
 @since 2020/12/15 0:20 */
public class MusicsFragment extends BaseFragment {
    private static final int WRITE_PERMISSION_REQUEST_CODE = 1;
    /** 是否忽略操作失败 */
    private static final boolean IGNORE_OPERATION_FAILURE = true;
    private RecyclerView content_rv;
    private MusicsAdapter adapter;
    private View view;
    private boolean readPermissionEnabled = false;

    private SeekBar playProgress_sb;
    private View left_v;
    private View center_v;
    private View right_v;

    private MediaPlayer mediaPlayer;

    private MenuDialog menuDialog;

    private MusicDetailDialog detailDialog;
    private RenameDialog renameDialog;

    private int lastLongClickPos = -1;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_musics, container, false);
        onBindView();
        onBindListener();
        onInitView();
        initMenuDialog();
        onLoadData();
        return view;
    }

    private void onBindView() {
        content_rv = view.findViewById(R.id.content_rv);
        playProgress_sb = view.findViewById(R.id.play_progress_sb);
        left_v = view.findViewById(R.id.left_v);
        center_v = view.findViewById(R.id.center_v);
        right_v = view.findViewById(R.id.right_v);

        Context context = requireContext();
        detailDialog = new MusicDetailDialog(context);
        renameDialog = new RenameDialog(context);
    }

    private void initMenuDialog() {
        menuDialog = new MenuDialog(requireContext());
        List<MenuItem> items = new ArrayList<>();
        items.add(new MenuItem(
                R.mipmap.ic_launcher,
                "查看详情",
                (item, pos) -> {
                    detailDialog.show(adapter.getMusicList().get(lastLongClickPos));
                    lastLongClickPos = -1;
                }
        ));
        items.add(new MenuItem(
                R.mipmap.ic_launcher,
                "重命名",
                (item, pos) -> {
                    if (onCheckPermission()) {
                        Music music = adapter.getMusicList().get(lastLongClickPos);
                        renameDialog.show(music.name, ".mp3", ".wav");
                    }
                }
        ));
        items.add(new MenuItem(
                R.mipmap.ic_launcher,
                "删除",
                (item, pos) -> {
                    Music music = adapter.getMusicList().get(lastLongClickPos);
                    File file = new File(music.path);
                    if (file.delete() || IGNORE_OPERATION_FAILURE) {
                        toast("删除成功");
                        adapter.getMusicList().remove(lastLongClickPos);
                        adapter.notifyItemRemoved(lastLongClickPos);
                    } else {
                        toast("删除失败");
                    }
                }
        ));
        menuDialog.setMenuItemList(items);
    }

    private void onBindListener() {
        adapter = new MusicsAdapter();
        adapter.setItemListener((view, pos, type) -> {
            switch (type) {
                default:
                case ItemListener.TYPE_DEFAULT:
                    String path = adapter.getMusicList().get(pos).path;
                    if (mediaPlayer != null) mediaPlayer.release();
                    mediaPlayer = MediaPlayer.create(requireContext(), Uri.parse(path));
                    if (mediaPlayer == null) {
                        toast("文件打开失败！");
                        return;
                    }
                    mediaPlayer.setOnCompletionListener(mp -> {
                        center_v.setSelected(false);
                        playProgress_sb.setProgress(mediaPlayer.getCurrentPosition());
                    });

                    playProgress_sb.setMax(mediaPlayer.getDuration());
                    playProgress_sb.setProgress(0);

                    mediaPlayer.start();
                    startAsyncUpdateProgress();
                    center_v.setSelected(true);
                    center_v.setEnabled(true);
                    break;
                case MusicsAdapter.TYPE_LONG_CLICK:
                    lastLongClickPos = pos;
                    menuDialog.show();
                    break;
            }
        });
        left_v.setOnClickListener(v -> {
            mediaPlayer.seekTo(0);
            playProgress_sb.setProgress(0);
        });
        center_v.setOnClickListener(v -> {
            if (!center_v.isSelected()) {
                mediaPlayer.start();
                startAsyncUpdateProgress();
                center_v.setSelected(true);
            } else {
                mediaPlayer.pause();
                center_v.setSelected(false);
                playProgress_sb.setProgress(mediaPlayer.getCurrentPosition());
            }
        });
        right_v.setOnClickListener(v -> toast("这玩意没啥用！"));
        playProgress_sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) { }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                mediaPlayer.seekTo(seekBar.getProgress());
            }
        });

        renameDialog.setOnConfirmListener(newName -> {
            Music music = adapter.getMusicList().get(lastLongClickPos);
            File file = new File(music.path);
            File newFile = new File(file.getParentFile(), newName);
            boolean success = false;
            try {
                Files.move(file.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
                success = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (success || IGNORE_OPERATION_FAILURE) {
                toast("重命名成功！");
                music.name = newName;
                adapter.notifyItemChanged(lastLongClickPos);
            } else {
                toast("重命名失败！");
            }
        });
    }

    private void onInitView() {
        content_rv.setAdapter(adapter);
        center_v.setEnabled(false);
    }

    private void onLoadData() {
        if (!readPermissionEnabled) return;
        if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.CREATED)) return;
        adapter.setDataAndNotify(getMusics(requireContext().getContentResolver()));
    }

    public List<Music> getMusics(ContentResolver contentResolver) {
        List<Music> videos = new ArrayList<>();
        try (Cursor c = contentResolver.query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                null, null, null,
                MediaStore.Audio.Media.DEFAULT_SORT_ORDER)) {
            int idIndex = c.getColumnIndex(MediaStore.Audio.Media._ID);
            int pathIndex = c.getColumnIndex(MediaStore.Audio.Media.DATA);
            int nameIndex = c.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME);
            int durationIndex = 0;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
                durationIndex = c.getColumnIndex(MediaStore.Audio.Media.DURATION);
            }

            int authorIndex = c.getColumnIndex(MediaStore.Audio.Media.ARTIST);
            int memoryIndex = c.getColumnIndex(MediaStore.Audio.Media.SIZE);
            while (c.moveToNext()) {
                Music music = new Music();
                music.id = getInt(c, idIndex);
                music.path = getString(c, pathIndex);
                music.name = getString(c, nameIndex);
                music.duration = getLong(c, durationIndex);
                music.author = getString(c, authorIndex);
                music.memorySize = getLong(c, memoryIndex);
                videos.add(music);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return videos;
    }

    public void onReadPermissionUpdate(boolean enabled) {
        readPermissionEnabled = enabled;
        if (enabled) onLoadData();
    }

    private void startAsyncUpdateProgress() {
        UpdateProgressTask task = new UpdateProgressTask();
        task.execute();
    }

    private class UpdateProgressTask extends AsyncTask<Integer, Integer, String> {
        @Override
        protected void onPostExecute(String s) { }

        @Override
        protected void onProgressUpdate(Integer... values) {
            playProgress_sb.setProgress(values[0]);
        }

        @Override
        protected String doInBackground(Integer... params) {
            while (center_v.isSelected()) {
                this.publishProgress(mediaPlayer.getCurrentPosition());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    }

    private boolean onCheckPermission() {
        if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.P
                || ContextCompat.checkSelfPermission(
                requireContext(),
                Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            toast("需要文件读取权限以读取本机文件");
        } else {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_PERMISSION_REQUEST_CODE);
        }
        return false;
    }
}
